## 工具类, 处理重复性无意义工作, 侧重节点相关的处理
## 寻找节点(表达式方式寻找), 初始化节点
## 算法: 裁剪表达式字符串, 生成对应的索引函数, 匹配对应的节点
## 继承: Node
class_name Util extends Node

##	查找节点
##	@param nodes 节点组
##	@param name 节点名
##	@return 节点组中对应节点名的节点
func findNode(nodes: Array[Node], nodeName: String) -> Node:
	for item in nodes:
		# 如果找到这个节点, 赋值并跳出循环
		if item.name == nodeName:
			return item
	return null


##	获得所有兄弟节点
##	@param selfNode 本节点
##	@return 所有兄弟节点, 包括自己
func getBrotherNodes(selfNode: Node) -> Array[Node]:
	return selfNode.get_parent().get_children()
	

##	获得指定名字的兄弟节点
##	@param 本节点
##	@param 兄弟节点名字
##	@return 兄弟节点
func getBrotherNode(selfNode: Node, brotherName: String) -> Node:
	return findNode(getBrotherNodes(selfNode), brotherName)


##	解析表达式中括号中的值
##	@param expression 表达式
##	@return 解析后的结果
func getExpressionValue(expression: String) -> String:
	expression = expression.replace(" ", "")
	var start = expression.find("[")
	var end = expression.find("]")
	return expression.substr(start + 1, end - 2) if start != -1 && end != -1 else ""
	

##	解析表达式中括号外的值
##	@param expression 表达式
##	@return 解析后的结果
func getExpressionKey(expression: String) -> String:
	return expression.substr(0, 1) if expression != null && expression != "" else ""

	
##	根据表达式规则查找第一个元素
##	- expression详解:
##		范围[标记]
##		
##	- 范围
##		!: 世界节点
##		@: 爷节点
##		#: 父节点
##		$: 子节点
##		
##	- 标记(省略默认第一个)
##		节点名 or 节点下标
##	
##	可以互相组合: 
##		![Box] 	从世界节点开始寻找所有子节点为Box的节点
##		#[0]  	寻找父节点下的第一个子节点
##		#		寻找父节点
##	@param expression 表达式
##	@param selfNode 本节点, 默认为空
##	@return 第一个符合条件的元素
func findOne(expression: String, selfNode: Node) -> Node:
	if selfNode == null:
		# 默认根节点
		return null
		
	var key = getExpressionKey(expression)
	
	if key == "" || key == null:
		return null
		
	var value = getExpressionValue(expression)
	
	# 只有key的情况
	if value == "":
		match key:
			"!":
				return selfNode.get_window().get_child(0)
				
			"@":
				var father = selfNode.get_parent()
				return father.get_parent() if father != null else null
				
			"#":
				return selfNode.get_parent()
				
			"$":
				var childCount = selfNode.get_child_count()
				return selfNode.get_child(0) if childCount > 0 else null
		
	
	# 在这一定是key value都存在
	# 这时候不再获取父节点本身, 而是从父节点向下查找
	# 下标模式
	if value.is_valid_int():
		value = value.to_int()
		match key:
			"!":
				return selfNode.get_window().get_child(0).get_child(value)
				
			"@":
				var father = selfNode.get_parent()
				var grandpa = father.get_parent() if father != null else null
				if grandpa != null:
					return grandpa.get_child(value)
					
			"#":
				var father = selfNode.get_parent()
				if father != null:
					return father.get_child(value)
				
			"$":
				var childCount = selfNode.get_child_count()
				if childCount > 0:
					return selfNode.get_child(value)
	
	# 节点名模式
	else:
		match key:
			"!":
				var root = selfNode.get_window().get_child(0).get_children()
				return findNode(root, value)
				
			"@":
				var father = selfNode.get_parent()
				var grandpa = father.get_parent() if father != null else null
				if grandpa != null:
					return findNode(grandpa.get_children(), value)
					
			"#":
				var father = selfNode.get_parent()
				if father != null:
					return findNode(father.get_children(), value)
				
			"$":
				return findNode(selfNode.get_children(), value)
				
	return null


## 初始化节点
## @param size 数组大小
## @param defaultValue 数组默认值
## @return 大小为size的初始化后的节点数组
func initArray(size: int, defaultValue: Variant) -> Array[Variant]:
	var array = []
	for i in size:
		array.append(defaultValue)
		
	return array


## 获得电脑MAC地址
func get_mac_address():
	var os_name = OS.get_name()
	var output = []
	var exit_code = -1
	
	match os_name:
		"Windows":
			# 使用 getmac 命令获取MAC地址
			exit_code = OS.execute("getmac", ["/fo", "csv", "/nh"], output)
			if exit_code == 0 and output.size() > 0:
				var lines = output[0].split("\n")
				for line in lines:
					line = line.strip_edges()
					if line != "" and "Device" not in line:
						var parts = line.split(",")
						if parts.size() >= 1:
							var mac = parts[0].replace("\"", "").strip_edges()
							if mac != "":
								return mac
		"X11", "macOS":
			# Linux使用ip命令，macOS类似
			exit_code = OS.execute("sh", ["-c", "ip link show | grep 'link/ether' | awk '{print $2}' | head -n 1"], output)
			if exit_code == 0 and output.size() > 0:
				var mac = output[0].strip_edges()
				if mac != "":
					return mac
		_:
			print("Unsupported OS: ", os_name)
	return ""	
